package com.yonyou.pmclouds.workquality.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.exception.BuziExCodeConst;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.util.SqlUtil;
import com.yonyou.pmclouds.businessobject.util.BulkDataSplitUtils;
import com.yonyou.pmclouds.offline.aspect.Offline;
import com.yonyou.pmclouds.offline.entity.OffLineDataKeyConst;
import com.yonyou.pmclouds.offline.entity.OffLineInvocationContext;
import com.yonyou.pmclouds.offline.rmiitf.IOffLineDataQueryService;
import com.yonyou.pmclouds.picture.entity.PictureVO;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.procedure.entity.ProcedureVO;
import com.yonyou.pmclouds.procedure.rmiitf.ProcedureQuery;
import com.yonyou.pmclouds.workquality.entity.WorkQualityCheckTypeWithBillTypeEnum;
import com.yonyou.pmclouds.workquality.entity.WorkqualityCheckTypeEnum;
import com.yonyou.pmclouds.workquality.entity.WorkqualityDetailVO;
import com.yonyou.pmclouds.workquality.entity.WorkqualityVO;
import com.yonyou.pmclouds.workquality.mapper.WorkqualityDetailMapper;
import com.yonyou.pmclouds.workquality.mapper.WorkqualityMapper;
import com.yonyou.pmclouds.workquality.service.rmiitf.WorkqualityQueryService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = WorkqualityQueryService.class)
@Offline(dataFrom = OffLineDataKeyConst.DATA_FROM_WORK_QUALITY)
public class WorkqualityQueryServiceImpl implements WorkqualityQueryService, IOffLineDataQueryService {

    @Autowired
    private WorkqualityMapper mapper;

    @Autowired
    private WorkqualityDetailMapper detailMapper;

    @Autowired
    private ProcedureQuery procedureQuery;

    @Autowired
    private PictureRemoteService pictureRemoteService;

    @Override
    public Map<String, Object> queryByCondition(String contidion, Integer start, Integer limit, byte enableStatus) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        List<WorkqualityVO> list = null;

        if (contidion != null) {
            String[] co = contidion.split(" ");
            if (co.length > 3) {
                co = Arrays.copyOfRange(co, 0, 3);
            }

            int total = mapper.countPage(co, RuntimeEnvironment.getTenantId(), enableStatus);
            if (total > 0) {
                list = mapper.queryByPage(co, RuntimeEnvironment.getTenantId(), start, limit, enableStatus);
            }


            /*
             * 新增返回值，检查项数量
             */
            if (list != null) {
                List<String> pkList = new ArrayList<>();
                for (WorkqualityVO vo : list) {
                    if (vo != null && vo.getPkWorkquality() != null) {
                        pkList.add(vo.getPkWorkquality());
                    }
                }
                List<WorkqualityDetailVO> detailVOList = null;
                if (pkList.size() > 0) {
                    detailVOList = detailMapper.queryByWorkqualityIds(SqlUtil.getSqlIn(pkList.toArray(new String[0])));
                }
                Map<String, Integer> recordDetailCount = new HashMap<>();
                if (detailVOList != null) {
                    for (WorkqualityDetailVO detailVO : detailVOList) {
                        if (detailVO != null && detailVO.getPkWorkquality() != null) {
                            String pk = detailVO.getPkWorkquality();
                            recordDetailCount.put(pk, recordDetailCount.get(pk) == null ? 1 : recordDetailCount.get(pk) + 1);
                        }
                    }
                }
                for (WorkqualityVO workqualityVO : list) {
                    if (workqualityVO != null && workqualityVO.getPkWorkquality() != null) {
                        String pk = workqualityVO.getPkWorkquality();
                        workqualityVO.setItemcount(recordDetailCount.get(pk) == null ? 0 : recordDetailCount.get(pk));
                    }
                }
            }

            map.put("total", total);
            map.put("result", list);
        }

        return map;
    }

    //===========无1
    @Override
    public WorkqualityVO queryByIDFull(String pk) throws BusinessException {
        WorkqualityVO vo = mapper.getById(pk);

        if (vo != null) {
            ProcedureVO procedureVO = procedureQuery.getById(vo.getPkProcedure());

            if (procedureVO != null) {
                vo.setProcedurename(procedureVO.getSname());
            }

            List<WorkqualityDetailVO> list = detailMapper.queryByWorkqualityId(vo.getPkWorkquality());
            setExamplePics(list);
            vo.setItemtabledata(list.toArray(new WorkqualityDetailVO[list.size()]));
            // FIXME 这个字段不可经常查询，会导致系统性能下降, 而且目前没有发现有代码使用了该字段
            int used = mapper.checkUpdateUsed(vo);
            if (used > 0) {
                vo.setUsed(true);
            }
        }
        return vo;
    }

    @Override
    public WorkqualityVO queryByID(String pk) throws BusinessException {
        WorkqualityVO vo = mapper.getById(pk);

        if (vo != null) {
            ProcedureVO procedureVO = procedureQuery.getById(vo.getPkProcedure());

            if (procedureVO != null) {
                vo.setProcedurename(procedureVO.getSname());
            }

            List<WorkqualityDetailVO> list = detailMapper.queryByWorkqualityId(vo.getPkWorkquality());
            setExamplePics(list);
            vo.setItemtabledata(list.toArray(new WorkqualityDetailVO[list.size()]));
//            // FIXME 这个字段不可经常查询，会导致系统性能下降, 而且目前没有发现有代码使用了该字段
//            int used = mapper.checkUpdateUsed(vo);
//            if (used > 0) {
//                vo.setUsed(true);
//            }
        }
        return vo;
    }

    /**
     * 设置示例照片
     *
     * @param list
     */
    //===========无2
    private void setExamplePics(List<WorkqualityDetailVO> list) throws BusinessException {
        if (list != null) {
            for (WorkqualityDetailVO detailVo : list) {
                detailVo.setExamplePictures(pictureRemoteService.queryExamplePicsByEntity(detailVo.getPkWorkqualitydetail()));
            }
        }
    }

    //============无3
    @Override
    public Map<String, WorkqualityVO> queryByIDs(String[] pks) throws BusinessException {
        if (ArrayUtils.isEmpty(pks)) {
            return new HashMap<>();
        }
        Map<String, WorkqualityVO> map = new HashMap<>();
        List<WorkqualityVO> vos = mapper.queryByIds(SqlUtil.getSqlIn(pks));
        for (WorkqualityVO vo : vos) {
            map.put(vo.getPkWorkquality(), vo);
        }
        return map;
    }

    @Override
    public WorkqualityVO queryByProcedure(String procedure) {
        return mapper.queryByProcedure(procedure);
    }

    @Override
    public WorkqualityVO queryByProcedureAndType(String procedure, String checkType) {
        int type = 0;
        switch (checkType) {
            case BillTypeConst.SIDE_INSPECTION_BILLTYPE:
                type = WorkqualityCheckTypeEnum.SITE.getValue();
                break;
            case BillTypeConst.PARALLEL_INSPECTION_BILLTYPE:
                type = WorkqualityCheckTypeEnum.PARALLEL.getValue();
                break;
            case BillTypeConst.PATROL_BILLTYPE:
                type = WorkqualityCheckTypeEnum.PATROL.getValue();
                break;
            default:
                type = WorkqualityCheckTypeEnum.GENERAL.getValue();
                break;

        }
        return mapper.queryOneByProcedureAndType(procedure, type);
    }

    //这个没看懂
    @Override
    public List<WorkqualityVO> queryWorkQualityByProcedureAndType(String procedure, String checkType, String tenantId) throws BusinessException {
        int type = 0;
        switch (checkType) {
            case BillTypeConst.SIDE_INSPECTION_BILLTYPE:
                type = WorkqualityCheckTypeEnum.SITE.getValue();
                break;
            case BillTypeConst.PARALLEL_INSPECTION_BILLTYPE:
                type = WorkqualityCheckTypeEnum.PARALLEL.getValue();
                break;
            case BillTypeConst.PATROL_BILLTYPE:
                type = WorkqualityCheckTypeEnum.PATROL.getValue();
                break;
            default:
                type = WorkqualityCheckTypeEnum.GENERAL.getValue();
                break;
        }

        List<WorkqualityVO> results = mapper.queryByProcedureAndType(procedure, type, tenantId);
        // 工序没有关联检查标准，则查询出所有未关联工序的检查标准
        if (results == null || results.size() == 0) {
            results = mapper.queryAllNotAssociatedChecks(tenantId, type);
        }

        return results;
    }

    //===========无4
    @Override
    public void referCheck(WorkqualityVO vo) throws BusinessException {
        Integer count = mapper.checkUpdateUsed(vo);
        if (count != null && count > 0)
            throw new BusinessException("检查标准已经被引用，不允许修改!", BuziExCodeConst.CODE_NAME_BEEN_USED);
    }

    public List<WorkqualityVO> queryByVO(WorkqualityVO vo) throws BusinessException {
        List<WorkqualityVO> vos = mapper.get(vo);
        return vos;
    }

    //=============无5
    @Override
    public List<WorkqualityVO> queryByChecktypes(String tenantId, int... checktypes) throws BusinessException {

        List<WorkqualityVO> workqualityVOS = mapper.queryByChecktypes(tenantId, checktypes);
        if (workqualityVOS == null) {
            workqualityVOS = Collections.emptyList();
        }
        return workqualityVOS;
    }


    @Override
    public WorkqualityDetailVO[] queryByProcedureCode(String pkTenant, String procedureCode) {
        return detailMapper.queryByProcedureCode(pkTenant, procedureCode);
    }

    @Override
    public List<WorkqualityVO> queryByPkProcedures(Set<String> pkProcedures) {
        return mapper.queryByPkProcedures(BulkDataSplitUtils.getSplitDataSet(pkProcedures));
    }

    //=============无6
    @Override
    public List<WorkqualityDetailVO> queryDetailByPkQualities(Set<String> pkWorkQualities) {
        return detailMapper.queryDetailByPkQualities(BulkDataSplitUtils.getSplitDataSet(pkWorkQualities));
    }

    //=============无7
    @Override
    public WorkqualityVO queryByIDForMobile(String pk) throws BusinessException {
        WorkqualityVO vo = mapper.getById(pk);

        if (vo != null) {
            ProcedureVO procedureVO = procedureQuery.getById(vo.getPkProcedure());

            if (procedureVO != null)
                vo.setProcedurename(procedureVO.getSname());

            List<WorkqualityDetailVO> list = detailMapper.queryEnableItemByWorkqualityId(vo.getPkWorkquality());
            setExamplePics(list);
            vo.setItemtabledata(list.toArray(new WorkqualityDetailVO[list.size()]));
        }

        return vo;
    }

    //=========无8 查询离线数据??
    @Override
    public Object queryOffLineData(OffLineInvocationContext invocationContext) throws BusinessException {
        // 查找该租住下所有的检查标准
        List<WorkqualityVO> workQualityVOList = queryByChecktypes(invocationContext.getTenantId(), null);

        if(workQualityVOList == null || workQualityVOList.size() <= 0){
            return new HashMap<String, List<WorkqualityVO>>();
        }

        setQualityDetail(workQualityVOList);

        return getQualityWithBillType(workQualityVOList);
    }

    @Override
    public Map<String, Map<String, List<WorkqualityVO>>> queryByProcedureIds(Set<String> pkProcedures) throws BusinessException {
        List<WorkqualityVO> workQualityVOList = mapper.queryByPkProcedures(BulkDataSplitUtils.getSplitDataSet(pkProcedures));

        if(workQualityVOList == null || workQualityVOList.size() <= 0){
            return new HashMap<>();
        }

        setQualityDetail(workQualityVOList);

        // 将质量标准按工序进行分类，key为工序主键
        Map<String, List<WorkqualityVO>> procedureIdMap = new HashMap<>();
        for(WorkqualityVO workqualityVO : workQualityVOList){
            List<WorkqualityVO> qualityList = procedureIdMap.get(workqualityVO.getPkProcedure());
            if(qualityList == null){
                qualityList = new ArrayList<>();
                qualityList.add(workqualityVO);
                procedureIdMap.put(workqualityVO.getPkProcedure(), qualityList);
            }else{
                qualityList.add(workqualityVO);
            }
        }

        Map<String, Map<String, List<WorkqualityVO>>> procedureWithTypeMap = new HashMap<>();
        for(Map.Entry<String, List<WorkqualityVO>> entry : procedureIdMap.entrySet()){
            List<WorkqualityVO> qualityVOS = entry.getValue();
            procedureWithTypeMap.put(entry.getKey(), getQualityWithBillType(qualityVOS));
        }
        return procedureWithTypeMap;
    }

    private void setQualityDetail(List<WorkqualityVO> workQualityVOList) throws BusinessException{

        Set<String> workQualityIdSet = new HashSet<>();
        for (WorkqualityVO workqualityVO : workQualityVOList) {
            workQualityIdSet.add(workqualityVO.getPkWorkquality());
        }

        // 查询检查标准下的所有检查项
        List<WorkqualityDetailVO> workQualityDetailVOS = detailMapper.queryDetailByPkQualities(BulkDataSplitUtils.getSplitDataSet(workQualityIdSet));

        Map<String, List<WorkqualityDetailVO>> workQualityDetailMap = new HashMap<>();
        List<String> pkQualityDetailList = new ArrayList<>();
        if (workQualityDetailVOS != null && workQualityDetailVOS.size() > 0) {
            for (WorkqualityDetailVO workqualityDetailVO : workQualityDetailVOS) {
                pkQualityDetailList.add(workqualityDetailVO.getPkWorkqualitydetail());

                List<WorkqualityDetailVO> detailVOList = workQualityDetailMap.get(workqualityDetailVO.getPkWorkquality());
                if (detailVOList == null) {
                    detailVOList = new ArrayList<>();
                    detailVOList.add(workqualityDetailVO);
                    workQualityDetailMap.put(workqualityDetailVO.getPkWorkquality(), detailVOList);
                } else {
                    detailVOList.add(workqualityDetailVO);
                }

            }

            // 查询检查项下面所有的标准图片
            Map<String, List<PictureVO>> pictureMap = pictureRemoteService.queryByLargePkEntities(pkQualityDetailList.toArray(new String[]{}));

            if (pictureMap != null) {
                for (WorkqualityDetailVO workqualityDetailVO : workQualityDetailVOS) {
                    List<PictureVO> pictureList = pictureMap.get(workqualityDetailVO.getPkWorkqualitydetail());
                    if (pictureList == null) {
                        pictureList = new ArrayList<>();
                    }
                    workqualityDetailVO.setExamplePictures(pictureList.toArray(new PictureVO[]{}));
                }
            }

            for (WorkqualityVO workqualityVO : workQualityVOList) {
                // 将检查项放入到检查标准中
                List<WorkqualityDetailVO> detailVOList = workQualityDetailMap.get(workqualityVO.getPkWorkquality());
                if (detailVOList == null) {
                    detailVOList = new ArrayList<>();
                }
                workqualityVO.setItemtabledata(detailVOList.toArray(new WorkqualityDetailVO[]{}));

            }
        }
    }

    private Map<String, List<WorkqualityVO>> getQualityWithBillType(List<WorkqualityVO> workQualityVOList){
        Map<String, List<WorkqualityVO>> workQualityMap = new HashMap<>();

        for (WorkqualityVO workqualityVO : workQualityVOList) {
            String checkType = workqualityVO.getChecktype();
            String billType = WorkQualityCheckTypeWithBillTypeEnum.getBillType(checkType);
            List<WorkqualityVO> workQualityVOS = workQualityMap.get(billType);
            if (workQualityVOS != null) {
                workQualityVOS.add(workqualityVO);
            } else {
                workQualityVOS = new ArrayList<>();
                workQualityVOS.add(workqualityVO);
                workQualityMap.put(billType, workQualityVOS);
            }
        }

        return workQualityMap;
    }
}
